package org.foliage.rcp.ui.custom;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.foliage.rcp.ui.preference.GanttMeasure;
import org.foliage.rcp.ui.preference.IGanttSettings;
import org.foliage.rcp.ui.widgets.Gantt;

public class GanttMeasureSetter extends FoliageDialog {

	// ----------------------------------------------- 

	private final Gantt gantt;

	private final IGanttSettings settings;

	// ----------------------------------------------- 

	private static Map<Integer, Integer> timeUnitMap = new HashMap<Integer, Integer>();
	static {
		timeUnitMap.put(0, Calendar.MINUTE);
		timeUnitMap.put(1, Calendar.HOUR_OF_DAY);
		timeUnitMap.put(2, Calendar.DAY_OF_MONTH);
	}
	private static Map<Integer, Integer> timeUnitReverseMap = new HashMap<Integer, Integer>();
	static {
		timeUnitReverseMap.put(Calendar.MINUTE, 0);
		timeUnitReverseMap.put(Calendar.HOUR_OF_DAY, 1);
		timeUnitReverseMap.put(Calendar.DAY_OF_MONTH, 2);
	}

	private static Map<Integer, String> timeFormatMap = new HashMap<Integer, String>();
	static {
		timeFormatMap.put(0, "MMM dd, ''HH");
		timeFormatMap.put(1, "HH:mm");
		timeFormatMap.put(2, "yyyy MMM");
	}
	private static Map<String, Integer> timeFormatReverseMap = new HashMap<String, Integer>();
	static {
		timeFormatReverseMap.put("MMM dd, ''HH", 0);
		timeFormatReverseMap.put("HH:mm", 1);
		timeFormatReverseMap.put("yyyy MMM", 2);
	}

	private static Map<Integer, Integer> modelMap = new HashMap<Integer, Integer>();
	static {
		modelMap.put(0, 2);
	}
	private static Map<Integer, Integer> modelReverseMap = new HashMap<Integer, Integer>();
	static {
		modelReverseMap.put(2, 0);
	}

	private static Map<Integer, Integer> alignMap = new HashMap<Integer, Integer>();
	static {
		alignMap.put(0, SWT.LEFT);
		alignMap.put(1, SWT.CENTER);
		alignMap.put(2, SWT.RIGHT);
	}
	private static Map<Integer, Integer> alignReverseMap = new HashMap<Integer, Integer>();
	static {
		alignReverseMap.put(SWT.LEFT, 0);
		alignReverseMap.put(SWT.CENTER, 1);
		alignReverseMap.put(SWT.RIGHT, 2);
	}

	private static Map<Integer, String> timeZoneMap = new HashMap<Integer, String>();
	static {
		timeZoneMap.put(0, "Etc/UTC");
		timeZoneMap.put(1, "Asia/Shanghai");
	}
	private static Map<String, Integer> timeZoneReverseMap = new HashMap<String, Integer>();
	static {
		timeZoneReverseMap.put("Etc/UTC", 0);
		timeZoneReverseMap.put("Asia/Shanghai", 1);
	}

	// ----------------------------------------------- 

	private class GanttMeasureComposite extends Composite {

		// ------------------------------------------- 

		private GanttMeasure measure;

		private Combo timeUnitCombo;
		private Combo timeZoneCombo;
		private Combo timeFormatCombo;
		private Combo alignCombo;
		private Combo modelCombo;

		private Spinner unitCountSpinner;
		private Spinner widthSpinner;

		// ------------------------------------------- 

		public GanttMeasureComposite(Composite parent, int style, final GanttMeasure measure) {
			super(parent, style);
			this.measure = measure;
			setLayout(new FillLayout(SWT.VERTICAL));
			{
				Group group = new Group(this, SWT.NONE);
				group.setText("时间格式");
				group.setLayout(new GridLayout(4, false));
				{
					Label label = new Label(group, SWT.NONE);
					label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
					label.setText("单位：");
				}
				{
					timeUnitCombo = new Combo(group, SWT.PUSH);
					timeUnitCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
					timeUnitCombo.add("分", 0);
					timeUnitCombo.add("时", 1);
					timeUnitCombo.add("日", 2);
					timeUnitCombo.addListener(SWT.Selection, new Listener() {

						@Override
						public void handleEvent(Event event) {
							measure.setUnit(timeUnitMap.get(timeUnitCombo.getSelectionIndex()));
						}

					});
				}
				{
					Label label = new Label(group, SWT.NONE);
					GridData data = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
					data.horizontalIndent = 10;
					label.setLayoutData(data);
					label.setText("标签：");
				}
				{
					timeFormatCombo = new Combo(group, SWT.PUSH);
					timeFormatCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
					timeFormatCombo.add("MMM dd, ''HH", 0);
					timeFormatCombo.add("HH:mm", 1);
					timeFormatCombo.add("yyyy MMM", 2);
					timeFormatCombo.addListener(SWT.Selection, new Listener() {

						@Override
						public void handleEvent(Event event) {
							measure.setDateFormat(timeFormatMap.get(timeFormatCombo.getSelectionIndex()));
						}

					});
				}
				{
					Label label = new Label(group, SWT.NONE);
					label.setText("计数：");
				}
				{
					unitCountSpinner = new Spinner(group, SWT.BORDER);
					unitCountSpinner.setSelection(1);
					unitCountSpinner.addListener(SWT.Modify, new Listener() {

						@Override
						public void handleEvent(Event event) {
							measure.setUnitCount(unitCountSpinner.getSelection());
						}

					});
				}
				{
					Label label = new Label(group, SWT.NONE);
					label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
					label.setText("对齐：");
				}
				{
					alignCombo = new Combo(group, SWT.PUSH);
					GridData data = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
					data.widthHint = 100;
					alignCombo.setLayoutData(data);
					alignCombo.add("居左", 0);
					alignCombo.addListener(SWT.Selection, new Listener() {

						@Override
						public void handleEvent(Event event) {
							measure.setAlign(alignMap.get(alignCombo.getSelectionIndex()));
						}

					});
				}
			}
			{
				Group group = new Group(this, SWT.NONE);
				group.setText("刻度模式");
				GridLayout layout = new GridLayout(4, false);
				layout.marginRight = 100;
				group.setLayout(layout);
				{
					Label label = new Label(group, SWT.NONE);
					label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
					label.setText("显示：");
				}
				{
					modelCombo = new Combo(group, SWT.PUSH);
					modelCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
					modelCombo.add("两层（中层、底层）", 0);
				}
				{
					Label label = new Label(group, SWT.NONE);
					GridData data = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
					data.horizontalIndent = 10;
					label.setLayoutData(data);
					label.setText("宽度：");
				}
				{
					widthSpinner = new Spinner(group, SWT.BORDER);
					widthSpinner.addListener(SWT.Modify, new Listener() {

						@Override
						public void handleEvent(Event event) {
							settings.setGanttMeasureWidth(widthSpinner.getSelection());
						}

					});
				}
				{
					Label label = new Label(group, SWT.NONE);
					label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
					label.setText("时区：");
				}
				{
					timeZoneCombo = new Combo(group, SWT.PUSH);
					timeZoneCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
					timeZoneCombo.add("Etc/UTC", 0);
					timeZoneCombo.add("Asia/Shanghai", 1);
					timeZoneCombo.addListener(SWT.Selection, new Listener() {

						@Override
						public void handleEvent(Event event) {
							settings.setTimeZone(TimeZone.getTimeZone(timeZoneMap.get(timeZoneCombo.getSelectionIndex())));
						}

					});
				}
				new Label(group, SWT.NONE);
				new Label(group, SWT.NONE);
			}
			reset();
		}

		public void reset() {
			setFormEnabled(measure != null);
			if (measure != null) {
				timeUnitCombo.select(timeUnitReverseMap.get(measure.getUnit()));
				timeFormatCombo.select(timeFormatReverseMap.get(measure.getDateFormat()));
				unitCountSpinner.setSelection(measure.getUnitCount());
				alignCombo.select(alignReverseMap.get(measure.getAlign()));
			}
			widthSpinner.setSelection(settings.getGanttMeasureWidth());
			timeZoneCombo.select(timeZoneReverseMap.get(settings.getTimeZone().getID()));
			modelCombo.select(modelReverseMap.get(settings.getGanttMeasureLevel()));
		}

		public void setFormEnabled(boolean isEnabled) {
			timeUnitCombo.setEnabled(isEnabled);
			timeFormatCombo.setEnabled(isEnabled);
			unitCountSpinner.setEnabled(isEnabled);
			alignCombo.setEnabled(isEnabled);
		}

	}

	// ----------------------------------------------- 

	public GanttMeasureSetter(Gantt gantt) {
		super(gantt.getShell(), SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
		this.gantt = gantt;
		this.settings = gantt.getGanttSettings();
	}

	// ----------------------------------------------- 

	@Override
	protected Control createBodyContent(Composite parent) {
		getShell().setText("时间刻度");
		Composite container = (Composite) super.createBodyContent(parent);
		container.setLayout(new FillLayout(SWT.HORIZONTAL));

		TabFolder tabFolder = new TabFolder(container, SWT.NONE);

		TabItem topItem = new TabItem(tabFolder, SWT.NONE);
		topItem.setText("顶层");
		final GanttMeasureComposite topComp = new GanttMeasureComposite(tabFolder, SWT.NONE, settings.getHeaderTopMeasure());
		topItem.setControl(topComp);

		TabItem middleItem = new TabItem(tabFolder, SWT.NONE);
		middleItem.setText("中层");
		final GanttMeasureComposite middleComp = new GanttMeasureComposite(tabFolder, SWT.NONE, settings.getHeaderMiddleMeasure());
		middleItem.setControl(middleComp);

		TabItem bottomItem = new TabItem(tabFolder, SWT.NONE);
		bottomItem.setText("底层");
		final GanttMeasureComposite bottomComp = new GanttMeasureComposite(tabFolder, SWT.NONE, settings.getHeaderBottomMeasure());
		bottomItem.setControl(bottomComp);

		tabFolder.addListener(SWT.Selection, new Listener() {

			@Override
			public void handleEvent(Event event) {
				topComp.reset();
				middleComp.reset();
				bottomComp.reset();
			}

		});

		return container;
	}

	@Override
	protected void createButtons(Composite parent) {
		createButton(parent, SWT.OK, "确定", true);
		createButton(parent, SWT.CANCEL, "取消", false);
	}

	// ----------------------------------------------- 

	@Override
	protected void okPressed() {
		gantt.getJointHandler().jointGanttSettings(settings);
		gantt.getJointHandler().jointGanttRedrawing();
		super.okPressed();
	}

	@Override
	protected Point getInitialSize() {
		return new Point(450, 300);
	}

}
